package com.camel.iamfx.market;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.camel.iamfx.base.BaseTableController;
import com.camel.iamfx.config.URLConstants;
import com.camel.iamfx.model.PluginJarInfo;
import com.camel.iamfx.utils.PluginClassLoader;
import com.camel.iamfx.utils.PluginManager;
import com.camel.iamfx.utils.PluginParser;
import com.xwintop.xcore.util.javafx.TooltipUtil;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.util.Callback;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.io.File;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.ResourceBundle;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import static com.camel.iamfx.utils.PluginParser.ENTRY_NAME;

@Slf4j
public class Controller extends BaseTableController<MarketEntity> implements Initializable {

    public ObservableList<MarketEntity> dataModel = FXCollections.observableArrayList();

    @FXML
    private TableView<MarketEntity> controlMarketTable;

    @FXML
    protected TableColumn<MarketEntity, String> downloadTableColumn;

    @FXML
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        addTableDataAdapter();
        reloadTable();

        downloadTableColumn.setCellFactory(
                new Callback<TableColumn<MarketEntity, String>, TableCell<MarketEntity, String>>() {
                    @Override
                    public TableCell<MarketEntity, String> call(TableColumn<MarketEntity, String> param) {
                        return new TableCell<MarketEntity, String>() {
                            @Override
                            protected void updateItem(String item, boolean empty) {
                                super.updateItem(item, empty);
                                this.setText(null);
                                if (!empty) {
                                    MarketEntity dataRow = dataModel.get(this.getIndex());
                                    Button downloadButton = new Button("下载");
                                    if (dataRow.isDownLoad()) {
                                        downloadButton.setText("已下载");
                                        downloadButton.setDisable(true);
                                    }

                                    if (dataRow.isUpdate()) {
                                        downloadButton.setText("更新");
                                        downloadButton.setDisable(false);
                                    }
                                    this.setContentDisplay(ContentDisplay.CENTER);
                                    downloadButton.setOnMouseClicked(event -> downloadPlugin(dataRow, downloadButton));
                                    this.setGraphic(downloadButton);
                                }
                            }
                        };
                    }
                }
        );
    }

    private void reloadTable() {
        // 添加数据
        try {
            dataModel.clear();
            dataModel.addAll(getTableData());
        } catch (Exception e) {
            TooltipUtil.showToast("插件市场加载失败");
        }
        controlMarketTable.setItems(dataModel);
        controlMarketTable.refresh();
    }

    /**
     * 获取表数据
     *
     * @return
     */
    private List<MarketEntity> getTableData() {
        String post = HttpUtil.post(URLConstants.MARKET_ENTITY_URL, "");
        JSONObject jsonObject = JSONObject.parseObject(post);
        JSONArray jsonArray = jsonObject.getJSONArray("data");
        List<MarketEntity> marketEntities = JSONArray.parseArray(JSONArray.toJSONString(jsonArray), MarketEntity.class);
        List<PluginJarInfo> pluginList = PluginManager.getInstance().getPluginList();
        for (PluginJarInfo pluginJarInfo : pluginList) {
            if (!StringUtils.isEmpty(pluginJarInfo.getFxmlPath())) {
                for (MarketEntity marketEntity : marketEntities) {
                    if (marketEntity.getJarName().equals(pluginJarInfo.getJarName())) {
                        if (!jarFileExists(pluginJarInfo.getJarName())) {
                            marketEntity.setDownLoad(false);
                            marketEntity.setUpdate(false);
                            pluginJarInfo.setIsDownload(false);
                            pluginJarInfo.setIsUpdate(false);
                        } else {
                            if (marketEntity.getVersion().equals(pluginJarInfo.getVersion())) {
                                pluginJarInfo.setIsDownload(true);
                                marketEntity.setDownLoad(true);
                            } else {
                                pluginJarInfo.setIsDownload(false);
                                pluginJarInfo.setIsUpdate(false);
                                marketEntity.setDownLoad(true);
                                marketEntity.setUpdate(true);
                            }
                        }

                    }
                }
            }
        }
        return marketEntities;
    }

    private boolean jarFileExists(String jarName) {
        File file = new File("libs/");
        if (!file.exists()) {
            return false;
        }
        String[] list = file.list();
        for (String s : list) {
            if (s.startsWith(jarName)) {
                return true;
            }
        }
        return false;

    }


    private void downloadPlugin(MarketEntity dataRow, Button downloadButton) {
        try {
            PluginManager instance = PluginManager.getInstance();
            PluginJarInfo plugin = instance.getPlugin(dataRow.getJarName());
            File file = plugin.getFile();
            HttpUtil.downloadFile(dataRow.getUrl(), file.getAbsolutePath());
            if (file.exists()) {
                try (JarFile jarFile = new JarFile(file)) {
                    JarEntry entry = jarFile.getJarEntry(ENTRY_NAME);
                    if (entry == null) {
                        return;
                    }
                }
            }


            PluginClassLoader tempClassLoader = new PluginClassLoader(plugin.getFile());
            PluginParser.parse(file, plugin, tempClassLoader);
            PluginManager.getInstance().saveToFileQuietly();
            TooltipUtil.showToast("下载插件成功");
            reloadTable();
        } catch (Exception e) {
            e.printStackTrace();
            TooltipUtil.showToast("下载插件失败");
        }
    }

    private void addTableDataAdapter() {
        HashMap<String, String> map = new HashMap<>();
        map.put("appName", "名称");
        map.put("tIndex", "序号");
        map.put("remark", "备注");
        map.put("version", "版本");
        map.put("jarSize", "大小");
        super.addTableDataAdapter(map);
    }

    @Override
    protected void optColumn() {
        ObservableList<TableColumn<MarketEntity, ?>> columns = controlMarketTable.getColumns();
        TableColumn<MarketEntity, ?> optColumn = columns.get(columns.size() - 1);
    }

    @Override
    protected TableView<MarketEntity> getTableControl() {
        return controlMarketTable;
    }
}
